import org.junit.jupiter.api.Test;

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.zone.ZoneRules;
import java.util.Map;
import java.util.Set;

/**
 * ZoneId是一个抽象类，它有两个实现类，其中ZoneRegion类用于表示时区，ZoneOffset用于表示与UTC时间的偏移量。
 * ZoneId分别提供了创建ZoneRegion类和ZoneOffset类的方法。
 */
public class ZoneIdDemo {

    /**
     * SHORT_IDS：是一个map集合，为我们提供了常用的时区的名称以及对应的简称。
     */
    @Test
    public void test01(){
        Map<String, String> shortIds = ZoneId.SHORT_IDS;
        for (Map.Entry<String, String> zone : shortIds.entrySet()) {
            System.out.println(zone.getKey()+":"+zone.getValue());
        }
        // NST:Pacific/Auckland
        // HST:-10:00
        // ACT:Australia/Darwin
        // BST:Asia/Dhaka
        // AET:Australia/Sydney
        // IST:Asia/Kolkata
        // CST:America/Chicago
        // NET:Asia/Yerevan
        // AGT:America/Argentina/Buenos_Aires
        // CAT:Africa/Harare
        // MIT:Pacific/Apia
        // BET:America/Sao_Paulo
        // PST:America/Los_Angeles
        // ART:Africa/Cairo
        // JST:Asia/Tokyo
        // VST:Asia/Ho_Chi_Minh
        // IET:America/Indiana/Indianapolis
        // CNT:America/St_Johns
        // PLT:Asia/Karachi
        // PNT:America/Phoenix
        // EST:-05:00
        // EAT:Africa/Addis_Ababa
        // ECT:Europe/Paris
        // PRT:America/Puerto_Rico
        // CTT:Asia/Shanghai
        // SST:Pacific/Guadalcanal
        // MST:-07:00
        // AST:America/Anchorage
    }
}

class ZoneIdDemo01 {

    /**
     * from(TemporalAccessor temporal)
     * 作用：从其他具有时区或偏移量概念的时间对象中获取zoneId对象。
     */
    @Test
    public void test01(){
        ZonedDateTime zonedDateTime01 = ZonedDateTime.now();
        OffsetDateTime offsetDateTimme01 = OffsetDateTime.now();
        ZoneId zoneId01 = ZoneId.from(zonedDateTime01);
        ZoneId zoneId02 = ZoneId.from(offsetDateTimme01);

        System.out.println(zoneId01); // 输出 Asia/Shanghai
        System.out.println(zoneId02); // 输出 +08:00
    }

    /**
     * getAvailableZoneIds()
     * 作用：获取所有时区的Id。
     */
    @Test
    public void test02(){
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        for (String zoneId : zoneIds) {
            System.out.println(zoneId);
        }
        // Asia/Aden
        // America/Cuiaba
        // Etc/GMT+9
        // Etc/GMT+8
        // Africa/Nairobi
        // ....
    }

    /**
     * of(String zoneId)
     * 作用：如果zoneId是时区的Id，那么创建的是ZoneRegion对象。
     *      如果是偏移量的格式，那么创建的是ZoneOffset对象。
     *
     * of(String zoneId, Map<String,String> aliasMap)
     * 作用：根据时区的Id创建ZoneRegion对象，aliasMap是映射时区Id的集合。
     *
     * ofOffset(String prefix, ZoneOffset offset)
     * 作用：获得一个封装偏移量的ZoneId对象。如果prefix为GMT、UTC或UT，
     *      返回ZoneRegion对象，否则返回ZoneOffset对象。
     */
    @Test
    public void test03(){
        ZoneId zoneId01 = ZoneId.of("Asia/Shanghai");
        ZoneId zoneId02 = ZoneId.of("+08:00");
        System.out.println(zoneId01.getClass()); // 输出 class java.time.ZoneRegion
        System.out.println(zoneId02.getClass()); // 输出 class java.time.ZoneOffset

        ZoneId zoneId03 = ZoneId.of("CTT", ZoneId.SHORT_IDS);
        System.out.println(zoneId03.getClass()); // 输出 class java.time.ZoneRegion
        System.out.println(zoneId03);// 输出 Asia/Shanghai

        ZoneOffset zoneOffset01 = ZoneOffset.of("+08:00");
        ZoneId zoneId04 = ZoneId.ofOffset("UTC", zoneOffset01);
        ZoneId zoneId05 = ZoneId.ofOffset("", zoneOffset01);
        System.out.println(zoneId04.getClass()); // 输出 class java.time.ZoneRegion
        System.out.println(zoneId04); // 输出 UTC+08:00
        System.out.println(zoneId05.getClass()); // 输出 class java.time.ZoneOffset
        System.out.println(zoneId05); // 输出 +08:00
    }

    /**
     * systemDefault()
     * 作用：获取操作系统的时区。
     */
    @Test
    public void test04(){
        System.out.println(ZoneId.systemDefault()); // 输出 Asia/Shanghai
    }
}

class ZoneIdDemo02 {

    /**
     * getId()
     * 作用：获取时区或偏移量的id。
     */
    @Test
    public void test01(){
        ZoneId zoneId01 = ZoneId.of("Asia/Shanghai");
        ZoneId zoneId02 = ZoneId.of("+08:00");
        System.out.println(zoneId01.getId()); // 输出 Asia/Shanghai
        System.out.println(zoneId02.getId()); // 输出 +08:00
    }

    /**
     * getRules()
     * 作用：获取时差的计算规则zoneRules对象。
     */
    @Test
    public void test02(){
        ZoneId zoneId01 = ZoneId.systemDefault();
        ZoneRules rules = zoneId01.getRules();
        System.out.println(rules); // 输出 ZoneRules[currentStandardOffset=+08:00]
    }

    /**
     * normalized()
     * 作用：返回该时区id的标准时区id字符串。如果该时区id已经是标准的时区id字符串，则返回该时区id本身。
     */
    @Test
    public void test03(){
        ZoneId zoneId = ZoneId.of("UTC");
        ZoneId normalizedZoneId = zoneId.normalized();
        System.out.println(zoneId); // 输出 UTC
        System.out.println(normalizedZoneId); // 输出 Z
    }
}